<?php


namespace Soen\Pool;


use Swoole\Coroutine\Channel;

class Pool implements PoolInterface
{
    /**
     * 最大活跃数
     * @var int
     */
    public $maxActiveCount = 5;

    /**
     * 最多可空闲数
     * @var int
     */
    public $maxFreeCount = 5;
    /**
     * @var Channel
     */
    protected $queue;
    /**
     * @var Connection[]
     */
    protected $actives = [];
    /**
     * @var DriverInterface
     */
    public $driver;

    public $connection;

    public function __construct($driver)
    {
        $this->driver = $driver;
        $this->queue = new Channel($this->maxFreeCount);
    }

    /**
     * 获取当前连接池 不同状态的数量
     * @return array
     */
    public function getConnCount(){
        $freeCount = $this->getFreeCount();
        return [
          'activeCount' =>  count($this->actives),
          'freeCount'   =>  $freeCount,
          'totalCount'  =>  $freeCount + count($this->actives)
        ];
    }

    /**
     * @return mixed
     */
    public function getFreeCount(){
        $count = $this->queue->length();
        return $count;
    }

    /**
     * 获取连接
     * @return Connection
     */
    public function createConnection():Connection
    {
        $connection = new Connection($this->driver);
        return $connection;
    }

    /**
     * 复用连接
     * @return mixed|Connection|null
     */
    public function reuse()
    {
        $connection = null;
        $activeCount = count($this->actives);
        if($activeCount < $this->maxActiveCount){
            if ($this->getFreeCount() > 0) {
                $connection = $this->pop();
            } else {
                $connection = $this->createConnection();
            }
        }
        $this->actives[$connection->getHashId()] = 1;
        return $connection;
    }

    /**
     * 归还连接/丢弃链接
     * @param Connection $connection
     * @param bool $close
     * @return bool|mixed|void
     */
    public function revert(Connection $connection, $close = false)
    {
        if(!isset($this->actives[$connection->getHashId()])){
            return false;
        }
        unset($this->actives[$connection->getHashId()]);
        if(!$close){
            return $this->push($connection);
        }
    }

    /**
     * 连接入列
     * @return mixed|void
     */
    public function push(Connection $connection)
    {
        $has = $this->queue->push($connection);
        return $has;
    }

    /**
     * 弹出 连接
     * @return mixed
     */
    public function pop()
    {
        /**
         * @var Connection
         */
        $connection = $this->queue->pop();
        $hashId = $connection->getHashId();
        $this->actives[$hashId] = 1;
        return $connection;
    }


}